//
//  ListUtils.m
//  sr01sdkProject
//
//  Created by Linktop on 2022/8/16.
//

#import "ListUtils.h"
#import "NSDictionary+SleepUsed.h"
#import "SleepStagingUtils.h"

@implementation ListUtils


///
/// @param data
/// @param timeMinute
/// 返回的数组中字典 String, Double, Double, Double
+(NSMutableArray <NSMutableDictionary *>*)segmentStandardDiviation:(NSMutableArray <NSMutableDictionary *>*) data TimeMinute:(int)timeMinute
{
    NSMutableArray <NSMutableDictionary *>* resultList;// = [NSMutableArray new];
    
    //将(时间，心率,计步)的集合修改成(数据下标，时间，心率，计步)的集合
    NSMutableArray <NSMutableDictionary *>* assignList = [NSMutableArray arrayWithCapacity:data.count];
    
    [data enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSMutableDictionary *mutDict = [NSMutableDictionary new];
        mutDict[FIRST] = @(idx);
        mutDict[SECOND] = obj.first;
        mutDict[THIRD] = obj.second;
        mutDict[FOURTH] = obj.third;
        assignList[idx] = mutDict;
    }];
    NSMutableArray <NSMutableArray <NSMutableDictionary *>*> *splitList = [self splitListByTime2:assignList TimeMinute:timeMinute];
    //拆分后的集合计算每个集合的平均值和标准差放入resultList 集合数据为(下标起始T下标截止,心率平均值,标准差)
    resultList = [NSMutableArray arrayWithCapacity:splitList.count];
    [splitList enumerateObjectsUsingBlock:^(NSMutableArray<NSMutableDictionary *> * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSMutableDictionary *dict = [NSMutableDictionary new];
       
        if (obj.count > 0) {
            // 下标起始T下标截止
            NSString *indexString = [NSString stringWithFormat:@"%@T%@", obj.firstObject.first,
                                     obj.lastObject.first];
            dict[FIRST] = indexString;
            // 心率平均值
            __block double thirdAvg = 0;
            NSMutableArray <NSNumber *>*hrArray = [NSMutableArray arrayWithCapacity:obj.count];
            __block double avgFourth = 0;
            [obj enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                thirdAvg += [obj.third doubleValue];
                hrArray[idx] = obj.third;
                avgFourth += [obj.fourth doubleValue];
            }];
            thirdAvg /= obj.count;
            avgFourth /= obj.count;
            dict[SECOND] = @(thirdAvg);
            // 标准差
            double Diviation = [self standardDiviation:hrArray];
            dict[THIRD] = @(Diviation);
            //
            dict[FOURTH] = @(avgFourth);
            
        }
        
    
        resultList[idx] = dict;
        
    }];
    
    return resultList;
    
}

//返回值 字典 Int, Long, Int, Int
+(NSMutableArray <NSMutableArray <NSMutableDictionary *>*> *)splitListByTime2:(NSMutableArray <NSMutableDictionary *>*)assignList TimeMinute:(int)timeMinute
{
    NSUInteger listSize = assignList.count;
    NSMutableArray <NSMutableArray <NSMutableDictionary *>*> *result = [NSMutableArray new];
    
    NSTimeInterval filterStartTime = [assignList.firstObject.second doubleValue];
    NSMutableDictionary * splitLastPoint = assignList.firstObject;
    NSTimeInterval endTime = [assignList.lastObject.second doubleValue];
    
    while (filterStartTime <= endTime) {
        NSTimeInterval filterEndTime = filterStartTime + timeMinute * 60;
        NSMutableArray<NSMutableDictionary *> *value = [NSMutableArray new];
        [assignList enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSTimeInterval interVal = [obj.second doubleValue];
            if (interVal >= filterStartTime && interVal < filterEndTime) {
                [value addObject:obj];
            }
            
        }];
    
        [result addObject:value];
        
        if (value.count > 0) {
            splitLastPoint = value.lastObject;
            filterStartTime = filterEndTime;
        } else {
            int findStartIndex = [splitLastPoint.first intValue] + 1;
            if (findStartIndex < listSize) {
                filterStartTime =  [assignList[findStartIndex].second doubleValue];
            } else {
                filterStartTime =  filterEndTime;
            }
        }
        
    }/* while */
    
    return result;
}


//标准差
+(double) standardDiviation:(NSArray <NSNumber *>*)x {
    NSUInteger m = x.count;
    __block double sum = 0.0;

    [x enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        sum += obj.doubleValue;
    }];
    double dAve = sum / m; //求平均值
    __block double dVar = 0.0;
    [x enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        dVar += (obj.doubleValue - dAve) * (obj.doubleValue - dAve);
    }];
    
    return sqrt(dVar / m);
}

/// 方差
+(double) variance:(NSArray <NSNumber *>*)x {
    NSUInteger m = x.count;
    double sum = 0.0;
    for (NSNumber *num in x) { //求和
        sum += num.doubleValue;
    }
    double dAve = sum / m; //求平均值
    double dVar = 0.0;
    for (NSNumber *num in x) { //求方差
        dVar += (num.doubleValue - dAve) * (num.doubleValue - dAve);
    }
    return dVar / m;
}

/**
   * 将列表里的数 按照数字连续 进行拆分
   * e.g [1,2,3,5,7,8,9]->{[1,2,3],[5],[7,8,9]}
   * @param indexArr 源List
   * return List<List<Int>> 拆分后的list
   */
+(NSMutableArray <NSMutableArray <NSNumber *>* >*)splitConsecutiveNumbers:(NSMutableArray<NSNumber *> *)indexArr
{
    NSMutableArray <NSMutableArray <NSNumber *>* >* ctList = [NSMutableArray new];// mutableListOf<MutableList<Int>>()
    __block NSMutableArray<NSNumber *> * seqList = [NSMutableArray new];//mutableListOf<Int>()
    __block int preIndex = indexArr.firstObject.intValue - 1;
    NSUInteger indexArrCount = indexArr.count;
    [indexArr enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        if (obj.intValue - 1 == preIndex) {
            [seqList addObject:obj];
        } else {
            [ctList addObject:seqList];//ctList.add(seqList)
            seqList = [NSMutableArray new];
            [seqList addObject:obj];
        }
        preIndex = obj.intValue;
        if (idx == indexArrCount - 1 && seqList.count > 0) {
            [ctList addObject:seqList];//ctList.add(seqList)
        }
    }];

    return ctList;
    
}

+(NSMutableArray <NSMutableDictionary *> *)calculateVariance2:(NSArray <NSMutableDictionary *> *)hrdata IntervalTime:(int)intervalTime Sd:(BOOL)sd UseInterval:(BOOL)useInterval
{
    NSMutableArray <NSMutableDictionary *> *  calList = [NSMutableArray new];
    if (hrdata.count == 0) {
        return calList;
    }
    //计算步数的标准差 平均值
    NSMutableArray <NSMutableDictionary *> *hrList = [NSMutableArray arrayWithCapacity:hrdata.count];
    [hrdata enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSMutableDictionary *dict = [NSMutableDictionary new];
        dict[FIRST] = @(idx);
        dict[SECOND] = obj.first;
        dict[THIRD] = obj.second;
        dict[FOURTH] = obj.third;
        hrList[idx] = dict;
    }];
    NSMutableArray <NSMutableDictionary *> *tempList = [NSMutableArray new];
    NSTimeInterval startTime = [hrList[0].second doubleValue];
    NSTimeInterval lastPointTime = startTime;
    for(int i = 0; i < hrList.count; i++) {
        
        //至少MIN_STANDARD_DEVIATION_AMOUNT个数据或小于间隔时间的数据 做计算,并且两两心率数据时间 不能超过MAX_HEART_RATE_INTERVAL
        if (([hrList[i].second doubleValue] - startTime <= intervalTime * 60
             || tempList.count < MIN_STANDARD_DEVIATION_AMOUNT)
            && [hrList[i].second doubleValue] - lastPointTime <= MAX_HEART_RATE_INTERVAL * 60
            ) {
            [tempList addObject:hrList[i]];
//            tempList.add(hrList[i])
        } else {
            [self addQuadrupleValue:calList TempList: tempList Sd:sd];
            if (useInterval) {
                [tempList removeObjectAtIndex:0];
//                tempList.removeFirst();
            } else {
                tempList = [NSMutableArray new];
            }
            [tempList addObject:hrList[i]];
//            tempList.add(hrList[i])
            startTime = [tempList.firstObject.second doubleValue];
        }
        lastPointTime = [hrList[i].second doubleValue];
        if (i == hrList.count - 1) {
            [self addQuadrupleValue:calList TempList:tempList Sd: sd];
        }
        
        
    }// for
    
    
    
    
    return calList;
}

+(void)addQuadrupleValue:(NSMutableArray <NSMutableDictionary *> *)calList  TempList:(NSMutableArray <NSMutableDictionary *> *)tempList Sd:(BOOL)sd
{
    if (tempList.count >= MIN_STANDARD_DEVIATION_AMOUNT) {
        NSMutableDictionary *dict = [NSMutableDictionary new];
        // tempList.first().first}T${tempList.last().first
        dict[FIRST] = [NSString stringWithFormat:@"%@T%@",tempList.firstObject.first,  tempList.lastObject.first];
        
        NSMutableArray<NSNumber *> *thirdArray = [NSMutableArray arrayWithCapacity:tempList.count];
        NSMutableArray<NSNumber *> *fourArray = [NSMutableArray arrayWithCapacity:tempList.count];
        __block double fourThAvg = 0;
        [tempList enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [thirdArray addObject:obj.third];
            [fourArray addObject:obj.fourth];
            fourThAvg += [obj.fourth doubleValue];
        }];
        fourThAvg /= tempList.count;
        
        if (sd) {
            dict[SECOND] = @([self standardDiviation:thirdArray]);
            dict[THIRD] = @([self standardDiviation:fourArray]);
        } else {
            dict[SECOND] = @([self variance:thirdArray]);
            dict[THIRD] = @([self variance:fourArray]);
            
        }
        dict[FOURTH] = @(fourThAvg);
        
        [calList addObject:dict];
        
    }
    else
    {
        NSMutableArray<NSNumber *> *thirdArray = [NSMutableArray arrayWithCapacity:tempList.count];
        NSMutableArray<NSNumber *> *fourArray = [NSMutableArray arrayWithCapacity:tempList.count];
        __block double fourThAvg = 0;
        [tempList enumerateObjectsUsingBlock:^(NSMutableDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [thirdArray addObject:obj.third];
            [fourArray addObject:obj.fourth];
            fourThAvg += [obj.fourth doubleValue];
            
        }];
        fourThAvg /= tempList.count;
        double hrSD = -1.0;
        double stepSD = -1.0;
        if (tempList.count >= 2) {
            if (sd) {
                hrSD = [self standardDiviation:thirdArray];
                stepSD = [self standardDiviation:fourArray];
            }
            else {
                hrSD = [self variance:thirdArray];
                stepSD = [self variance:fourArray];
            }
        }
        NSMutableDictionary *dict = [NSMutableDictionary new];
        dict[FIRST] = [NSString stringWithFormat:@"%@T%@",tempList.firstObject.first,  tempList.lastObject.first];
        
        dict[SECOND] = @(hrSD);
        dict[THIRD] = @(stepSD);
        dict[FOURTH] = @(fourThAvg);
        
        [calList addObject:dict];
        /*  calList.add(
         Quadruple(
         "${tempList.first().first}T${tempList.last().first}",
         hrSD,
         stepSD,
         tempList.map { it.fourth }.average()
         )
         ) */
    }
    
}


@end
